//Copyright(c)[2025][AGIROS][TravoDDS] is licensed under Mulan PSL v2.
//
//You can use this software according to the terms and conditions of
//the Mulan PSL v2.You may obtain a copy of Mulan PSL v2 at :
//http://license.coscl.org.cn/MulanPSL2
//
//THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF
//ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
//
//See the Mulan PSL v2 for more details.

#ifndef DYNAMIC_TYPE_H
#define DYNAMIC_TYPE_H

#include "travodds_dll.h"
#include "xtypes/dynamictypemember.h"
#include "xtypes/typedescriptor.h"
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <atomic>

TRAVODDS_NAMESPACE_BEGIN

/**
 * @brief DynamicType类表示根据类型系统定义的特定类型。
 * 
 * @details DynamicType对象具有引用语义，因为预计存在大量对它们的引用（例如，在每个从给定DynamicType创建的DynamicData对象中）。
 *          然而，该类型仍然提供操作以允许按值复制和比较。
 */
class DDS_DLL DynamicType {
public:
    /** @brief  关联的类型描述。 */
    TypeDescriptor descriptor_;

    /**
     * @brief 目前所有应用于此类型的注释。
     */
    std::vector<AnnotationDescriptor> annotation_;

    /**
     * @brief 成员ID到成员的映射
     * 
     * @details 如果此类型是聚合类型，通过此属性可用的成员集合应等于通过member_by_name属性可用的成员集合（元素顺序除外）。
     *          如果此类型不是聚合类型，成员集合应为空。
     */
    std::map<MemberId, DynamicTypeMember> member_;

    /**
     * @brief 成员名称到成员的映射
     * 
     * @details 此属性包含从此类型的成员名称到成员本身的映射。如下表所述，不仅聚合类型的成员被视为“成员”：枚举、位掩码和其他类型的组成部分也被视为此属性的“成员”。
     * 
     *          类型种类 | 行为
     *          ANNOTATION_TYPE | 成员描述符必须描述一致的注释类型成员。如果描述符不满足这些约束，操作将失败并返回RETCODE_BAD_PARAMETER。
     *          ALIAS_TYPE | 行为与别名的基类型相同。如果基类型未定义添加成员，则此操作将失败并返回RETCODE_PRECONDITION_NOT_MET。
     *          BITMASK_TYPE | 成员描述符必须描述一个布尔标志，其值在此位掩码类型的范围内。如果描述符不满足这些约束，操作将失败并返回RETCODE_BAD_PARAMETER。
     *          ENUMERATION_TYPE | 成员描述符必须描述一个具有此枚举类型的字面量。如果描述符不满足这些约束，操作将失败并返回RETCODE_BAD_PARAMETER。
     *          STRUCTURE_TYPE | 成员描述符必须描述一致的结构成员。如果描述符不满足此约束，操作将失败并返回RETCODE_BAD_PARAMETER。
     *          UNION_TYPE | 成员描述符必须描述一致的联合成员。如果描述符不满足此约束，操作将失败并返回RETCODE_BAD_PARAMETER。
     * 
     *          DynamicTypeMember对象的生命周期由包含它的DynamicType的生命周期管理。前者应被认为从相应成员添加到后者时起逻辑上存在，直到后者被删除为止。
     *          实现可以更频繁地分配和释放DynamicTypeMember对象，前提是：
     * 
     *          - DynamicTypeMember类的用户不需要显式删除该类的对象。
     *          - 对表示给定成员的一个DynamicTypeMember对象的更改应反映在表示相同成员的所有可观察DynamicTypeMember对象中。
     *          - 所有表示相同成员的DynamicTypeMember对象应根据其equals操作比较为相等。
     */
    std::map<std::string, DynamicTypeMember> member_by_name_;
public:
    /** 
     * @brief 根据指定的类型描述构造对象。
     */
    DynamicType(const TypeDescriptor& descriptor);

    /**
     * @brief 析构函数
     */
    ~DynamicType();

    /**
     * @brief 判断两个类型是否相等
     * 
     * @param other 另一个类型
     * 
     * @return bool 相等返回true，否则返回false
     */
    bool equals(const DynamicType& other) const;

    /**
     * @brief 获取注释数量。
     * 
     * @return 注释数量。
     */
    unsigned int get_annotation_count() const;

    /**
     * @brief 获取指定索引的注释
     * 
     * @param descriptor [in,out]   应用程序提供的对象
     * @param index 注释索引
     * 
     * @return 成功返回RETCODE_OK，失败返回RETCODE_BAD_PARAMETER
     */
    ReturnCode_t get_annotation(AnnotationDescriptor& descriptor, unsigned int index) const;

    /**
     * @brief 获取类型描述符
     * 
     * @param descriptor [in,out]   应用程序提供的对象
     * 
     * @return 成功返回RETCODE_OK，失败返回RETCODE_BAD_PARAMETER
     */
    ReturnCode_t get_descriptor(TypeDescriptor& descriptor) const;

    /**
     * @brief 获取类型种类
     * 
     * @return TypeKind 类型种类
     */
    TypeKind get_kind() const;

    /**
     * @brief 获取指定成员ID的成员
     * 
     * @param member [in,out]   用户提供的对象。
     * @param id 成员ID
     * 
     * @return 成功返回RETCODE_OK，失败返回RETCODE_BAD_PARAMETER
     */
    ReturnCode_t get_member(DynamicTypeMember& member, MemberId id) const;

    /**
     * @brief 获取指定索引的成员
     *
     * @param member [in,out]   用户提供的对象。 
     * @param index 成员索引
     * 
     * @return 成功返回RETCODE_OK，失败返回RETCODE_BAD_PARAMETER
     */
    ReturnCode_t get_member_by_index(DynamicTypeMember& member, unsigned int index) const;

    /**
     * @brief 获取指定名称的成员。
     *
     * @param member [in,out]   用户提供的对象。 
     * @param name 成员名称。
     * 
     * @return 成功返回RETCODE_OK，失败返回RETCODE_BAD_PARAMETER
     */
    ReturnCode_t get_member_by_name(DynamicTypeMember& member, const std::string& name) const;

    /**
     * @brief 获取成员数量
     * 
     * @return size_t 成员数量
     */
    size_t get_member_count() const;
    
    /**
     * @brief 获取类型名称
     * 
     * @return std::string 类型名称
     */
    std::string get_name() const;

private:
    // Prevent copying
    DynamicType(const DynamicType&);
    DynamicType& operator=(const DynamicType&);
public:
    /**
     * @brief 递增引用计数。
     */
    void increment_ref_count();

    /**
     * @brief 递减引用计数。
     */
    void decrement_ref_count();

    /**
     * @brief 获取引用计数。
     * 
     * @return 引用计数。
     */
    int get_ref_count() const;
private:
    /** @brief  引用计数。 */
    std::atomic<int> ref_count_;  
};

TRAVODDS_NAMESPACE_END

#endif // DYNAMIC_TYPE_H
